//! `std::os` 模块的测试用例
//!
//! 本文件包含对 `std::os` 中特定于操作系统的功能的测试。
//! 测试内容会根据目标操作系统 (如 Unix, Windows) 的不同而有所区别。

#[cfg(test)]
mod tests {
    // --- 通用 OS 信息 ---
    use std::env;

    /// 测试获取操作系统相关信息
    #[test]
    fn test_os_info() {
        // `env::consts::OS` 返回编译时的目标操作系统
        println!("编译目标操作系统: {}", env::consts::OS);
        // `env::consts::FAMILY` 返回操作系统家族 (如 "unix", "windows")
        println!("操作系统家族: {}", env::consts::FAMILY);
        // `env::consts::DLL_EXTENSION` 返回动态链接库的扩展名
        println!("动态链接库扩展名: {}", env::consts::DLL_EXTENSION);

        assert!(!env::consts::OS.is_empty());
    }

    // --- Unix 特有功能测试 ---
    #[cfg(unix)]
    mod unix_tests {
        use std::fs;
        use std::fs::File;
        use std::os::unix::fs::{MetadataExt, PermissionsExt};
        use std::os::unix::io::{AsRawFd, FromRawFd};
        /// 测试 Unix 文件元数据
        #[test]
        fn test_unix_metadata() {
            let temp_dir = tempfile::tempdir().unwrap();
            let file_path = temp_dir.path().join("test.txt");
            let file = File::create(&file_path).unwrap();

            let metadata = file.metadata().unwrap();

            // `mode()` 返回文件的权限和类型信息
            println!("文件模式 (mode): {:o}", metadata.mode());
            // `uid()` 和 `gid()` 返回用户ID和组ID
            println!("用户 ID (uid): {}", metadata.uid());
            println!("组 ID (gid): {}", metadata.gid());

            // 检查文件模式是否为普通文件
            assert_eq!(metadata.mode() & 0o170000, 0o100000);
        }

        /// 测试 Unix 文件权限
        #[test]
        fn test_unix_permissions() {
            let temp_dir = tempfile::tempdir().unwrap();
            let file_path = temp_dir.path().join("perms.txt");
            File::create(&file_path).unwrap();

            let mut perms = fs::metadata(&file_path).unwrap().permissions();

            // 设置权限为 rwxr-x--- (0o750)
            perms.set_mode(0o750);
            fs::set_permissions(&file_path, perms).unwrap();

            let new_perms = fs::metadata(&file_path).unwrap().permissions();
            assert_eq!(new_perms.mode() & 0o777, 0o750);
        }

        /// 测试原始文件描述符 (Raw FD)
        #[test]
        fn test_raw_fd() {
            let temp_dir = tempfile::tempdir().unwrap();
            let file_path = temp_dir.path().join("fd_test.txt");
            let file = File::create(&file_path).unwrap();

            // 获取原始文件描述符
            let raw_fd = file.as_raw_fd();
            println!("原始文件描述符: {}", raw_fd);
            assert!(raw_fd > 2); // 应该不是 stdin, stdout, stderr

            // 从原始文件描述符创建一���新的 File 实例
            // 注意：这会转移所有权，所以原来的 `file` 不能再使用
            let new_file = unsafe { File::from_raw_fd(raw_fd) };
            // 此时 `new_file` 和 `file` 指向同一个文件描述符
            // 当 `new_file` 被 drop 时，文件描述符会被关闭
        }
    }

    // --- Windows 特有功能测试 ---
    #[cfg(windows)]
    mod windows_tests {
        use std::fs::File;
        use std::os::windows::fs::MetadataExt;
        use std::os::windows::io::{AsRawHandle, FromRawHandle};

        /// 测试 Windows 文件元数据
        #[test]
        fn test_windows_metadata() {
            let temp_dir = tempfile::tempdir().unwrap();
            let file_path = temp_dir.path().join("test.txt");
            File::create(&file_path).unwrap();

            let metadata = std::fs::metadata(&file_path).unwrap();

            // `file_attributes()` 返回文件的属性
            let attributes = metadata.file_attributes();
            println!("文件属性: {}", attributes);

            // `creation_time()` 返回文件创建时间
            let creation_time = metadata.creation_time();
            println!("文件创建时间: {}", creation_time);

            // 检查是否为普通文件 (没有设置 `FILE_ATTRIBUTE_DIRECTORY`)
            const FILE_ATTRIBUTE_DIRECTORY: u32 = 0x10;
            assert_eq!(attributes & FILE_ATTRIBUTE_DIRECTORY, 0);
        }

        /// 测试原始句柄 (Raw Handle)
        #[test]
        fn test_raw_handle() {
            let temp_dir = tempfile::tempdir().unwrap();
            let file_path = temp_dir.path().join("handle_test.txt");
            let file = File::create(&file_path).unwrap();

            // 获取原始句柄
            let raw_handle = file.as_raw_handle();
            println!("原始句柄: {:?}", raw_handle);
            assert!(!raw_handle.is_null());

            // 从原始句柄创建一个新的 File 实例
            // 注意：这会转移所有权
            let new_file = unsafe { File::from_raw_handle(raw_handle) };
        }
    }
}
